<?php

abstract class WildliveActions extends sfActions
{
  const CONFIG_SECURITY_KEY_DYNAMIC_CREDENTIALS = 'dynamic_credentials';
  const CONFIG_SECURITY_KEY_DYNAMIC_CREDENTIALS_IS_ENABLED = 'is_enabled';
  const CONFIG_SECURITY_KEY_DYNAMIC_CREDENTIALS_PARSER = 'parser_class';
  const CONFIG_SECURITY_KEY_DYNAMIC_CREDENTIALS_OPTIONS = 'options';

  public function getCredential ()
  {
    $credentials = parent::getCredential();
    
    $config = $this->getSecurityValue(self::CONFIG_SECURITY_KEY_DYNAMIC_CREDENTIALS, array());
    if (isset($config[self::CONFIG_SECURITY_KEY_DYNAMIC_CREDENTIALS_IS_ENABLED]) && $config[self::CONFIG_SECURITY_KEY_DYNAMIC_CREDENTIALS_IS_ENABLED])
    {
      $parser_class = null;
      if (isset($config[self::CONFIG_SECURITY_KEY_DYNAMIC_CREDENTIALS_PARSER]))
      {
        $parser_class = $config[self::CONFIG_SECURITY_KEY_DYNAMIC_CREDENTIALS_PARSER];
      }
      
      $default_options = array(
        'actions' => $this);
      if (isset($config[self::CONFIG_SECURITY_KEY_DYNAMIC_CREDENTIALS_OPTIONS]))
      {
        $options = $config[self::CONFIG_SECURITY_KEY_DYNAMIC_CREDENTIALS_OPTIONS];
      }
      else
      {
        $options = array();
      }
      $options = array_merge($options, $default_options);
      
      $parser = $this->getCredentialParser($parser_class, $options);
      $credentials = $this->transformCredentials($credentials, $parser);
      
      $this->getLogger()
        ->debug('Transformed required credentials for current action: ' . print_r($credentials, true));
    }
    
    return $credentials;
  }

  /**
   * @param string|array $credentials
   * @param AbstractCredentialParser $parser
   * @return string|array
   */
  protected function transformCredentials ($credentials, AbstractCredentialParser $parser)
  {
    if (is_array($credentials))
    {
      foreach ($credentials as $k => $v)
      {
        $credentials[$k] = $this->transformCredentials($v, $parser);
      }
    }
    else
    {
      $credentials = $parser->parse($credentials);
    }
    return $credentials;
  }

  /**
   * @param string $class_name
   * @param array $options
   * @return AbstractCredentialParser
   */
  protected function getCredentialParser ($class_name, array $options)
  {
    if (is_null($class_name))
    {
      $class_name = 'DefaultCredentialParser';
    }
    
    if (class_exists($class_name, true))
    {
      return new $class_name($options);
    }
    else
    {
      throw new sfException(sprintf('Class "%s" not found.', $class_name));
    }
  }
}